/**
 * 
 */
package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.Timer;

import com.alee.extended.transition.ComponentTransition;
import com.alee.extended.transition.TransitionListener;
import com.alee.extended.transition.effects.Direction;
import com.alee.extended.transition.effects.curtain.CurtainTransitionEffect;
import com.alee.extended.transition.effects.curtain.CurtainType;
import com.alee.laf.checkbox.WebCheckBox;
import com.alee.laf.scroll.WebScrollPane;
import com.alee.utils.SwingUtils;

import model.Recipe;

import controller.Controls;

/**
 * Panel to provide search options for recipes.
 * 
 * @author
 */
public class SearchPanel extends JPanel implements ItemListener, ActionListener, KeyListener {
    /**
     * Serial Version ID.
     */
    private static final long serialVersionUID = -3279816271922871553L;
    //Testing Fields
    /**
     * List of Cuisines.
     */
    private static final List<String> CUISINES = Arrays.asList("Mexican", "Italian","Chinese", "Japanese", "German",
        "Southern", "American", "Asian", "African", "Indian", "Thai", "French", "Spanish"); 
    /**
     * Array of courses.
     */
    private static final List<String> COURSES = Arrays.asList("Main Dish", "Side Dish", "Appetizer", "Dessert", "Sauce",
        "Salad", "Drinks", "Breakfast");
    /**
     * Array of Difficulties
     */
    private static final List<String> DIFFICULTY = Arrays.asList("Easy", "Intermediate", "Difficult");
    //End of Testing fields
    private static final String[] ATTRIBUTES = {"SEARCHSTRING", "Cuisine", "Course", "Difficulty", "Prep_Time", "Cooking_Time", "Ingredient"};
    
    private static final Dimension SEARCH_MAX = new Dimension(450, 1000); 
    private static final Dimension CHECK_PANEL_MAX = new Dimension(125, 200); 
    private static final Dimension FIELD_MAX = new Dimension(350, 20);
    private static final Dimension PREP_MAX = new Dimension(30, 20);
    private static final Dimension FIELD_PANEL_MAX = new Dimension(350, 30);
    
    private static final Color CHECK_BOX_COLOR = Color.white;
    private static final String S_CUISINE = "Cuisines";
    
    private static final String S_COURSE = "Courses";
    
    private static final String S_DIFFICULTY = "Difficulty";
    private static final Timer timer = new Timer(3000, null);
    
    private final Controls my_controller;
    
    private final List<String> my_cuisines;
    
    private final List<String> my_courses;
    
    private final List<String> my_difficulty;
    
    private JTextField my_searchField;
    
    private JTextField my_ingredientField;
    
    private JTextField my_prepField;
    
    private JTextField my_cookField;
    private JButton my_searchButton;
    private JLabel my_resultLabel;
    private JLabel my_blank;
    private ComponentTransition my_transition;
    private List<JCheckBox> my_cuisineButtons;
    private List<JCheckBox> my_courseButtons;
    private List<JCheckBox> my_difficultyButtons;
    
    
    public SearchPanel(Controls the_controller) {
        my_controller = the_controller;
        my_cuisines = my_controller.getCuisines();
        my_courses = my_controller.getCourses();
        my_difficulty = my_controller.getDifficulty(); 
        my_cuisineButtons = new ArrayList<JCheckBox>();
        my_courseButtons = new ArrayList<JCheckBox>();
        my_difficultyButtons = new ArrayList<JCheckBox>();
        timer.addActionListener(this);
        timer.setRepeats(false);
        setupSearchPanel();
        
    }
    //TEST constructor
    public SearchPanel(Controls the_controller, String the_test) {
        my_controller = the_controller;
        my_cuisines = CUISINES;
        my_courses = COURSES;
        my_difficulty = DIFFICULTY;
        my_cuisineButtons = new ArrayList<JCheckBox>();
        my_courseButtons = new ArrayList<JCheckBox>();
        my_difficultyButtons = new ArrayList<JCheckBox>();
        setupSearchPanel();
    }
    public void setupSearchPanel() {
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        this.setBorder(BorderFactory.createEmptyBorder(60, 80, 40, 80));
        this.setMaximumSize(SEARCH_MAX);
        JPanel cuisinePanel = buildCheckPanel(my_cuisines, S_CUISINE);
        JPanel coursePanel = buildCheckPanel(my_courses, S_COURSE);
        JPanel difficultyPanel = buildCheckPanel(my_difficulty, S_DIFFICULTY);
        BackgroundPanel searchButton = buildSearchButton();
        
        //Initialize and Format TextFields
        formatTextFields();
        
        //Create Labels
        my_resultLabel = new JLabel("No Search Results");
        
        JLabel ingredientLabel = new JLabel("List Ingredients You Have: ");
        JLabel prepLabel = new JLabel("Max Prep Time:  ", JLabel.RIGHT);
        JLabel cookLabel = new JLabel("Max Cook Time: ", JLabel.RIGHT);
        JLabel minLabel1 = new JLabel(" min", JLabel.LEFT);
        JLabel minLabel = new JLabel(" min", JLabel.LEFT);
        my_resultLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 16));
        prepLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
        cookLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
        minLabel1.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
        minLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
        //Tranition panel
        my_transition = labelTransition();
        my_transition.setOpaque(false);
        //Create Field Panels
        JPanel resultLabelHolder = new JPanel();
        resultLabelHolder.add(my_transition);
        JPanel searchPanel = new JPanel();
        searchPanel.setLayout(new BoxLayout(searchPanel, BoxLayout.X_AXIS));
        JPanel ingredientPanel = new JPanel();

        JPanel prepPanel = new JPanel();
        //prepPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 150));
        
        JPanel cookPanel = new JPanel();
        //cookPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 150));
      
        searchPanel.add(my_searchField);
        searchPanel.add(searchButton);
        ingredientPanel.add(ingredientLabel);
        //ingredientPanel.add(my_ingredientField);
        prepPanel.add(prepLabel);
        prepPanel.add(my_prepField);
        prepPanel.add(minLabel1);
        cookPanel.add(cookLabel);
        cookPanel.add(my_cookField);
        cookPanel.add(minLabel);
        //Panel Sizing
        searchPanel.setMaximumSize(FIELD_PANEL_MAX);
        ingredientPanel.setMaximumSize(FIELD_PANEL_MAX);
        prepPanel.setMaximumSize(FIELD_PANEL_MAX);
        cookPanel.setMaximumSize(FIELD_PANEL_MAX);
        JPanel filler = new JPanel();
        filler.setOpaque(false);
        filler.setPreferredSize(new Dimension(400, 50));
        filler.setMaximumSize(getPreferredSize());
        //Build final panel
        this.add(resultLabelHolder);
        this.add(searchPanel);
        this.add(filler);
        this.add(ingredientPanel);
        this.add(my_ingredientField);
        this.add(prepPanel);
        this.add(cookPanel);
        JPanel attrGrid = new JPanel(new GridLayout(1, 3));
        attrGrid.add(cuisinePanel);
        attrGrid.add(coursePanel);
        attrGrid.add(difficultyPanel);
        attrGrid.setMaximumSize(new Dimension(400, 1000));
        this.add(attrGrid);  
        //Opacity
        resultLabelHolder.setOpaque(false);
        my_resultLabel.setOpaque(false);
        ingredientPanel.setOpaque(false);
        cuisinePanel.setOpaque(false);
        coursePanel.setOpaque(false);
        difficultyPanel.setOpaque(false);
        prepLabel.setOpaque(false);
        ingredientLabel.setOpaque(false);
        cookLabel.setOpaque(false);
        minLabel1.setOpaque(false);
        minLabel.setOpaque(false);
        cookPanel.setOpaque(false);
        prepPanel.setOpaque(false);
        attrGrid.setOpaque(false);
    }
    private void formatTextFields() {
        my_searchField = new JTextField();
        my_ingredientField = new JTextField();
        my_prepField = new JTextField();
        my_cookField = new JTextField();
        //set Hints
        my_searchField.setUI(new HintTextFieldUI("Search Recipe Titles", true));
        my_ingredientField.setUI(new HintTextFieldUI("Example: red bell pepper, pork, carrot", true));
        //set field size
        my_prepField.setPreferredSize(PREP_MAX);
        my_cookField.setPreferredSize(PREP_MAX);
        //my_searchField.setPreferredSize(new Dimension(325, 20));
        my_searchField.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 16));
        my_ingredientField.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
        my_ingredientField.setMaximumSize(FIELD_MAX);
        //Add keyListener
        my_searchField.addKeyListener(this);
        my_ingredientField.addKeyListener(this);
        my_prepField.addKeyListener(this);
        my_cookField.addKeyListener(this);
        
    }
    private JPanel buildCheckPanel(List<String> the_list, String the_title) {
        JPanel checkPanel = new JPanel(new GridLayout(0, 1));
        //checkPanel.setMaximumSize(CHECK_PANEL_MAX);
        for (int i = 0; i < the_list.size(); i++) {
            WebCheckBox checkButton = new WebCheckBox(the_list.get(i));
            checkButton.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
            checkButton.setOpaque(false);
            //checkButton.setBackground(CHECK_BOX_COLOR);
            checkButton.addItemListener(this);
            checkButton.addKeyListener(this);
            checkPanel.add(checkButton);
            if (the_title.equals(S_CUISINE)) {
                my_cuisineButtons.add(checkButton);
            } else if (the_title.equals(S_COURSE)) {
                my_courseButtons.add(checkButton);
            } else {
                my_difficultyButtons.add(checkButton);
            }
        }
        checkPanel.setBackground(CHECK_BOX_COLOR);
        JPanel result = new JPanel();
        result.setLayout(new BoxLayout(result, BoxLayout.Y_AXIS));
        JLabel titleLabel = new JLabel(the_title, JLabel.LEFT);
        titleLabel.setOpaque(false);
        //titleLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
        result.add(titleLabel);
        WebScrollPane scrollPanel = new WebScrollPane(checkPanel);
        scrollPanel.getViewport().setOpaque(false);
        scrollPanel.setOpaque(false);
        result.add(scrollPanel);
        //result.setMaximumSize(CHECK_PANEL_MAX);
        return result;
    }
    private BackgroundPanel buildSearchButton() {
        my_searchButton = new JButton();
        BackgroundPanel searchIcon = new BackgroundPanel(BackgroundPanel.createBackgroundImage(this, "Backgrounds/search.png"), 0);
        searchIcon.setMaximumSize(new Dimension(25, 25));
        //searchB.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
        my_searchButton.setContentAreaFilled(false);
        searchIcon.add(my_searchButton, BorderLayout.CENTER);
        my_searchButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent the_event) {
                List<String> sResult = new ArrayList<String>();
                addSearchResult(sResult, 0, my_searchField.getText());
                if (isInteger(my_prepField.getText())) {
                    addSearchResult(sResult, 4, my_prepField.getText());
                }
                if (isInteger(my_cookField.getText())) {
                    addSearchResult(sResult, 5, my_cookField.getText());
                }
                for (int i = 0; i < my_cuisineButtons.size(); i++) {
                    if (my_cuisineButtons.get(i).isSelected()) {
                        addSearchResult(sResult, 1, my_cuisineButtons.get(i).getText());
                    }
                }
                for (int i = 0; i < my_courseButtons.size(); i++) {
                    if (my_courseButtons.get(i).isSelected()) {
                        addSearchResult(sResult, 2, my_courseButtons.get(i).getText());
                    }
                }
                for (int i = 0; i < my_difficultyButtons.size(); i++) {
                    if (my_difficultyButtons.get(i).isSelected()) {
                        addSearchResult(sResult, 3, my_difficultyButtons.get(i).getText());
                    }
                }
                addSearchIngredients(sResult);
                if (sResult.size() > 1) {
                    if (my_controller.search(sResult)) {
                        my_controller.goSearchResults();
                    } else {
                        my_transition.performTransition(my_resultLabel);
                    }
                }
            }
        });
        return searchIcon;
    }
    private void addSearchResult(List<String> the_list, int the_index, String the_text) {
        if (the_text != null && !the_text.isEmpty()) {
            the_list.add(ATTRIBUTES[the_index]);
            the_list.add(the_text);
        }
    }
    private void addSearchIngredients(List<String> the_list) {
        String allIngredients = my_ingredientField.getText();
        if (allIngredients != null && !allIngredients.isEmpty()) {
            List<String> items = Arrays.asList(allIngredients.split("\\s*,\\s*"));
            for (int i = 0; i < items.size(); i++) {
                the_list.add(ATTRIBUTES[6]);
                the_list.add(items.get(i));
            }
        }
    }
    @Override
    public void itemStateChanged(ItemEvent arg0) {
        // TODO Auto-generated method stub       
    }
    private ComponentTransition labelTransition() {
        final ComponentTransition componentTransition = new ComponentTransition ();

        // Transition effect
        final CurtainTransitionEffect effect = new CurtainTransitionEffect ();
        effect.setType ( CurtainType.fade );
        effect.setSize ( 10 );
        effect.setSpeed ( 2 );
        effect.setDirection(Direction.right);
        componentTransition.setTransitionEffect ( effect );
        my_blank = new JLabel("         ");
        my_blank.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 16));
        my_blank.setBackground(Color.WHITE);
        // Initial transition panel state
        componentTransition.setContent (my_blank);
        componentTransition.setPreferredSize(SwingUtils.max(my_resultLabel, my_blank));

        // States switch button
        /*final WebButton switchView = new WebButton ( loadIcon ( "switch.png" ) );
        switchView.setDrawFocus ( false );
        switchView.addActionListener ( new ActionListener ()
        {
            public void actionPerformed ( ActionEvent e )
            {
                if ( componentTransition.getContent () == toolBar1 )
                {
                    effect.setDirection ( Direction.right );
                    componentTransition.performTransition ( toolBar2 );
                }
                else
                {
                    effect.setDirection ( Direction.left );
                    componentTransition.performTransition ( toolBar1 );
                }
            }
        } );*/
        componentTransition.addTransitionListener (new TransitionListener ()
        {
            public void transitionStarted ()
            {
             
            }

            public void transitionFinished ()
            {
                if (my_transition.getContent() == my_resultLabel) {
                    timer.start();
                    //my_transition.performTransition(my_blank);                 
                }
            }
        } );
        return componentTransition;
    }
    @Override
    public void actionPerformed(ActionEvent arg0) {
        my_transition.performTransition(my_blank);
    }
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyChar()==KeyEvent.VK_ENTER) {
            my_searchButton.doClick();
        }      
        
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }
    private static boolean isInteger(String s) {
        try { 
            Integer.parseInt(s); 
        } catch(NumberFormatException e) { 
            return false; 
        }
        // only got here if we didn't return false
        return true;
    }
}
